﻿using System;
using System.Collections.Generic;
using System.Linq;
using Helpers;
using TaleWorlds.CampaignSystem.Actions;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.ComponentInterfaces;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.CampaignSystem.Siege;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.LinQuick;
using TaleWorlds.Localization;
using TaleWorlds.SaveSystem;

namespace TaleWorlds.CampaignSystem.MapEvents
{
	// Token: 0x020002B9 RID: 697
	public class MapEventSide
	{
		// Token: 0x0600291E RID: 10526 RVA: 0x000AF930 File Offset: 0x000ADB30
		internal static void AutoGeneratedStaticCollectObjectsMapEventSide(object o, List<object> collectedObjects)
		{
			((MapEventSide)o).AutoGeneratedInstanceCollectObjects(collectedObjects);
		}

		// Token: 0x0600291F RID: 10527 RVA: 0x000AF940 File Offset: 0x000ADB40
		protected virtual void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
		{
			collectedObjects.Add(this._battleParties);
			collectedObjects.Add(this._mapEvent);
			collectedObjects.Add(this._mapFaction);
			UniqueTroopDescriptor.AutoGeneratedStaticCollectObjectsUniqueTroopDescriptor(this._selectedSimulationTroopDescriptor, collectedObjects);
			collectedObjects.Add(this._selectedSimulationTroop);
			collectedObjects.Add(this._nearbyPartiesAddedToPlayerMapEvent);
			collectedObjects.Add(this.LeaderParty);
		}

		// Token: 0x06002920 RID: 10528 RVA: 0x000AF9A6 File Offset: 0x000ADBA6
		internal static object AutoGeneratedGetMemberValueLeaderParty(object o)
		{
			return ((MapEventSide)o).LeaderParty;
		}

		// Token: 0x06002921 RID: 10529 RVA: 0x000AF9B3 File Offset: 0x000ADBB3
		internal static object AutoGeneratedGetMemberValueMissionSide(object o)
		{
			return ((MapEventSide)o).MissionSide;
		}

		// Token: 0x06002922 RID: 10530 RVA: 0x000AF9C5 File Offset: 0x000ADBC5
		internal static object AutoGeneratedGetMemberValueCasualtyStrength(object o)
		{
			return ((MapEventSide)o).CasualtyStrength;
		}

		// Token: 0x06002923 RID: 10531 RVA: 0x000AF9D7 File Offset: 0x000ADBD7
		internal static object AutoGeneratedGetMemberValueStrengthRatio(object o)
		{
			return ((MapEventSide)o).StrengthRatio;
		}

		// Token: 0x06002924 RID: 10532 RVA: 0x000AF9E9 File Offset: 0x000ADBE9
		internal static object AutoGeneratedGetMemberValueRenownValue(object o)
		{
			return ((MapEventSide)o).RenownValue;
		}

		// Token: 0x06002925 RID: 10533 RVA: 0x000AF9FB File Offset: 0x000ADBFB
		internal static object AutoGeneratedGetMemberValueInfluenceValue(object o)
		{
			return ((MapEventSide)o).InfluenceValue;
		}

		// Token: 0x06002926 RID: 10534 RVA: 0x000AFA0D File Offset: 0x000ADC0D
		internal static object AutoGeneratedGetMemberValueCasualties(object o)
		{
			return ((MapEventSide)o).Casualties;
		}

		// Token: 0x06002927 RID: 10535 RVA: 0x000AFA1F File Offset: 0x000ADC1F
		internal static object AutoGeneratedGetMemberValueIsSurrendered(object o)
		{
			return ((MapEventSide)o).IsSurrendered;
		}

		// Token: 0x06002928 RID: 10536 RVA: 0x000AFA31 File Offset: 0x000ADC31
		internal static object AutoGeneratedGetMemberValue_battleParties(object o)
		{
			return ((MapEventSide)o)._battleParties;
		}

		// Token: 0x06002929 RID: 10537 RVA: 0x000AFA3E File Offset: 0x000ADC3E
		internal static object AutoGeneratedGetMemberValue_mapEvent(object o)
		{
			return ((MapEventSide)o)._mapEvent;
		}

		// Token: 0x0600292A RID: 10538 RVA: 0x000AFA4B File Offset: 0x000ADC4B
		internal static object AutoGeneratedGetMemberValue_mapFaction(object o)
		{
			return ((MapEventSide)o)._mapFaction;
		}

		// Token: 0x0600292B RID: 10539 RVA: 0x000AFA58 File Offset: 0x000ADC58
		internal static object AutoGeneratedGetMemberValue_selectedSimulationTroopIndex(object o)
		{
			return ((MapEventSide)o)._selectedSimulationTroopIndex;
		}

		// Token: 0x0600292C RID: 10540 RVA: 0x000AFA6A File Offset: 0x000ADC6A
		internal static object AutoGeneratedGetMemberValue_selectedSimulationTroopDescriptor(object o)
		{
			return ((MapEventSide)o)._selectedSimulationTroopDescriptor;
		}

		// Token: 0x0600292D RID: 10541 RVA: 0x000AFA7C File Offset: 0x000ADC7C
		internal static object AutoGeneratedGetMemberValue_selectedSimulationTroop(object o)
		{
			return ((MapEventSide)o)._selectedSimulationTroop;
		}

		// Token: 0x0600292E RID: 10542 RVA: 0x000AFA89 File Offset: 0x000ADC89
		internal static object AutoGeneratedGetMemberValue_nearbyPartiesAddedToPlayerMapEvent(object o)
		{
			return ((MapEventSide)o)._nearbyPartiesAddedToPlayerMapEvent;
		}

		// Token: 0x17000A5C RID: 2652
		// (get) Token: 0x0600292F RID: 10543 RVA: 0x000AFA96 File Offset: 0x000ADC96
		// (set) Token: 0x06002930 RID: 10544 RVA: 0x000AFA9E File Offset: 0x000ADC9E
		[SaveableProperty(4)]
		public PartyBase LeaderParty { get; internal set; }

		// Token: 0x17000A5D RID: 2653
		// (get) Token: 0x06002931 RID: 10545 RVA: 0x000AFAA7 File Offset: 0x000ADCA7
		public MBReadOnlyList<MapEventParty> Parties
		{
			get
			{
				return this._battleParties;
			}
		}

		// Token: 0x17000A5E RID: 2654
		// (get) Token: 0x06002932 RID: 10546 RVA: 0x000AFAAF File Offset: 0x000ADCAF
		// (set) Token: 0x06002933 RID: 10547 RVA: 0x000AFAB7 File Offset: 0x000ADCB7
		[SaveableProperty(7)]
		public BattleSideEnum MissionSide { get; private set; }

		// Token: 0x17000A5F RID: 2655
		// (get) Token: 0x06002934 RID: 10548 RVA: 0x000AFAC0 File Offset: 0x000ADCC0
		private IBattleObserver BattleObserver
		{
			get
			{
				return this._mapEvent.BattleObserver;
			}
		}

		// Token: 0x17000A60 RID: 2656
		// (get) Token: 0x06002935 RID: 10549 RVA: 0x000AFACD File Offset: 0x000ADCCD
		public int TroopCount
		{
			get
			{
				return this.RecalculateMemberCountOfSide();
			}
		}

		// Token: 0x06002936 RID: 10550 RVA: 0x000AFAD8 File Offset: 0x000ADCD8
		public int CountTroops(Func<FlattenedTroopRosterElement, bool> pred)
		{
			int num = 0;
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				foreach (FlattenedTroopRosterElement arg in mapEventParty.Troops)
				{
					if (pred(arg))
					{
						num++;
					}
				}
			}
			return num;
		}

		// Token: 0x06002937 RID: 10551 RVA: 0x000AFB68 File Offset: 0x000ADD68
		public int GetTotalHealthyTroopCountOfSide()
		{
			int num = 0;
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				num += mapEventParty.Party.MemberRoster.TotalHealthyCount;
			}
			return num;
		}

		// Token: 0x06002938 RID: 10552 RVA: 0x000AFBCC File Offset: 0x000ADDCC
		public int GetTotalHealthyHeroCountOfSide()
		{
			int num = 0;
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				TroopRoster memberRoster = mapEventParty.Party.MemberRoster;
				num += memberRoster.TotalHeroes - memberRoster.TotalWoundedHeroes;
			}
			return num;
		}

		// Token: 0x17000A61 RID: 2657
		// (get) Token: 0x06002939 RID: 10553 RVA: 0x000AFC38 File Offset: 0x000ADE38
		public int NumRemainingSimulationTroops
		{
			get
			{
				List<UniqueTroopDescriptor> simulationTroopList = this._simulationTroopList;
				if (simulationTroopList == null)
				{
					return 0;
				}
				return simulationTroopList.Count;
			}
		}

		// Token: 0x17000A62 RID: 2658
		// (get) Token: 0x0600293A RID: 10554 RVA: 0x000AFC4B File Offset: 0x000ADE4B
		// (set) Token: 0x0600293B RID: 10555 RVA: 0x000AFC53 File Offset: 0x000ADE53
		[SaveableProperty(15)]
		public float CasualtyStrength { get; private set; }

		// Token: 0x17000A63 RID: 2659
		// (get) Token: 0x0600293C RID: 10556 RVA: 0x000AFC5C File Offset: 0x000ADE5C
		public MapEvent MapEvent
		{
			get
			{
				return this._mapEvent;
			}
		}

		// Token: 0x17000A64 RID: 2660
		// (get) Token: 0x0600293D RID: 10557 RVA: 0x000AFC64 File Offset: 0x000ADE64
		public MapEventSide OtherSide
		{
			get
			{
				return this._mapEvent.GetMapEventSide((this.MissionSide == BattleSideEnum.Defender) ? BattleSideEnum.Attacker : BattleSideEnum.Defender);
			}
		}

		// Token: 0x17000A65 RID: 2661
		// (get) Token: 0x0600293E RID: 10558 RVA: 0x000AFC7D File Offset: 0x000ADE7D
		public IFaction MapFaction
		{
			get
			{
				return this._mapFaction ?? this.LeaderParty.MapFaction;
			}
		}

		// Token: 0x0600293F RID: 10559 RVA: 0x000AFC94 File Offset: 0x000ADE94
		internal MapEventSide(MapEvent mapEvent, BattleSideEnum missionSide, PartyBase leaderParty)
		{
			this._mapEvent = mapEvent;
			this.LeaderParty = leaderParty;
			this.MissionSide = missionSide;
			this._mapFaction = leaderParty.MapFaction;
			this._battleParties = new MBList<MapEventParty>();
		}

		// Token: 0x06002940 RID: 10560 RVA: 0x000AFCE9 File Offset: 0x000ADEE9
		internal void CacheLeaderSimulationModifier()
		{
			this.LeaderSimulationModifier = Campaign.Current.Models.MilitaryPowerModel.GetLeaderModifierInMapEvent(this._mapEvent, this.MissionSide);
		}

		// Token: 0x06002941 RID: 10561 RVA: 0x000AFD11 File Offset: 0x000ADF11
		internal void AddPartyInternal(PartyBase party)
		{
			this._battleParties.Add(new MapEventParty(party));
			this._mapEvent.AddInvolvedPartyInternal(party, this.MissionSide);
		}

		// Token: 0x06002942 RID: 10562 RVA: 0x000AFD38 File Offset: 0x000ADF38
		internal void RemovePartyInternal(PartyBase party)
		{
			int index = this._battleParties.FindIndexQ((MapEventParty p) => p.Party == party);
			this._battleParties.RemoveAt(index);
			this._mapEvent.RemoveInvolvedPartyInternal(party);
			if (this.LeaderParty == party)
			{
				this._mapFaction = this.LeaderParty.MapFaction;
				if (this._battleParties.Count > 0)
				{
					this.LeaderParty = this._battleParties[0].Party;
					this.CacheLeaderSimulationModifier();
					return;
				}
				this.MapEvent.FinalizeEvent();
			}
		}

		// Token: 0x06002943 RID: 10563 RVA: 0x000AFDE0 File Offset: 0x000ADFE0
		public int RecalculateMemberCountOfSide()
		{
			int num = 0;
			foreach (MapEventParty mapEventParty in this.Parties)
			{
				num += mapEventParty.Party.NumberOfHealthyMembers;
			}
			return num;
		}

		// Token: 0x06002944 RID: 10564 RVA: 0x000AFE40 File Offset: 0x000AE040
		public float RecalculateStrengthOfSide()
		{
			float num = 0f;
			foreach (MapEventParty mapEventParty in this.Parties)
			{
				num += mapEventParty.Party.TotalStrength;
			}
			return num;
		}

		// Token: 0x06002945 RID: 10565 RVA: 0x000AFEA4 File Offset: 0x000AE0A4
		internal void DistributeLootAmongWinners(LootCollector lootCollector)
		{
			int num = this.CalculateTotalContribution();
			lootCollector.MakeFreedHeroesEscape(lootCollector.LootedPrisoners, this.MapEvent.IsPlayerMapEvent && this.MapEvent.PlayerSide == this.MapEvent.WinningSide);
			if ((float)num > 1E-05f)
			{
				MapEventParty[] array = new MapEventParty[this._battleParties.Count];
				this._battleParties.CopyTo(array);
				foreach (MapEventParty partyRec in array)
				{
					int num2 = this.CalculateContributionAndGiveShareToParty(lootCollector, partyRec, num);
					num -= num2;
				}
			}
			lootCollector.MakeRemainingPrisonerHeroesEscape();
		}

		// Token: 0x06002946 RID: 10566 RVA: 0x000AFF40 File Offset: 0x000AE140
		private int CalculateContributionAndGiveShareToParty(LootCollector lootCollector, MapEventParty partyRec, int totalContribution)
		{
			if (partyRec.Party.MemberRoster.Count > 0)
			{
				float lootAmount = (float)partyRec.ContributionToBattle / (float)totalContribution;
				lootCollector.GiveShareOfLootToParty(partyRec.RosterToReceiveLootMembers, partyRec.RosterToReceiveLootPrisoners, partyRec.RosterToReceiveLootItems, partyRec.Party, lootAmount, this._mapEvent);
				return partyRec.ContributionToBattle;
			}
			return 0;
		}

		// Token: 0x06002947 RID: 10567 RVA: 0x000AFF98 File Offset: 0x000AE198
		public bool IsMainPartyAmongParties()
		{
			return this.Parties.AnyQ((MapEventParty party) => party.Party == PartyBase.MainParty);
		}

		// Token: 0x06002948 RID: 10568 RVA: 0x000AFFC4 File Offset: 0x000AE1C4
		public float GetPlayerPartyContributionRate()
		{
			int num = this.CalculateTotalContribution();
			if (num == 0)
			{
				return 0f;
			}
			int num2 = 0;
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				if (mapEventParty.Party == PartyBase.MainParty)
				{
					num2 = mapEventParty.ContributionToBattle;
					break;
				}
			}
			return (float)num2 / (float)num;
		}

		// Token: 0x06002949 RID: 10569 RVA: 0x000B0040 File Offset: 0x000AE240
		internal int CalculateTotalContribution()
		{
			int num = 0;
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				if (mapEventParty.Party.MemberRoster.Count > 0)
				{
					num += mapEventParty.ContributionToBattle;
				}
			}
			return num;
		}

		// Token: 0x0600294A RID: 10570 RVA: 0x000B00AC File Offset: 0x000AE2AC
		public void CalculateRenownAndInfluenceValues(float[] strengthOfSide)
		{
			int missionSide = (int)this.MissionSide;
			int oppositeSide = (int)this.MissionSide.GetOppositeSide();
			float x = 1f;
			float num = 1f;
			if (this._mapEvent.IsSiegeAssault)
			{
				float settlementAdvantage = Campaign.Current.Models.CombatSimulationModel.GetSettlementAdvantage(this._mapEvent.MapEventSettlement);
				if (this.MissionSide == BattleSideEnum.Defender)
				{
					num = settlementAdvantage;
				}
				else
				{
					x = settlementAdvantage;
				}
			}
			float num2 = this._mapEvent.IsSiegeAssault ? 0.7f : ((this._mapEvent.IsSallyOut || this._mapEvent.IsRaid || this._mapEvent.MapEventSettlement != null) ? 0.6f : 0.5f);
			this.StrengthRatio = (strengthOfSide[oppositeSide] * MathF.Sqrt(x) + 10f) / (strengthOfSide[missionSide] * num + 10f);
			this.StrengthRatio = ((this.StrengthRatio > 10f) ? 10f : this.StrengthRatio);
			if (strengthOfSide[missionSide] > 0f)
			{
				this.RenownValue = MathF.Pow(strengthOfSide[oppositeSide] * MathF.Sqrt(x), 0.75f) * MathF.Pow(this.StrengthRatio, 0.45f) * num2 * 0.75f;
				this.InfluenceValue = MathF.Pow(strengthOfSide[oppositeSide] * MathF.Sqrt(x), 0.75f) * MathF.Pow(this.StrengthRatio, 0.15f) * 0.6f;
			}
		}

		// Token: 0x0600294B RID: 10571 RVA: 0x000B0210 File Offset: 0x000AE410
		internal void CommitXpGains()
		{
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				mapEventParty.CommitXpGain();
			}
		}

		// Token: 0x0600294C RID: 10572 RVA: 0x000B0260 File Offset: 0x000AE460
		public virtual void DistributeRenownAndInfluence(MapEventResultExplainer resultExplainers = null, bool forScoreboard = false)
		{
			int num = this.CalculateTotalContribution();
			float renownValue = this.RenownValue;
			float influenceValue = this.InfluenceValue;
			List<MobileParty> list = new List<MobileParty>();
			List<MobileParty> list2 = new List<MobileParty>();
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				PartyBase party = mapEventParty.Party;
				if (party.IsMobile && party.MobileParty.IsVillager)
				{
					list.Add(party.MobileParty);
				}
				if (party.IsMobile && party.MobileParty.IsCaravan)
				{
					list2.Add(party.MobileParty);
				}
			}
			foreach (MapEventParty mapEventParty2 in this._battleParties)
			{
				PartyBase party2 = mapEventParty2.Party;
				if (num > 0)
				{
					float num2 = (float)mapEventParty2.ContributionToBattle / (float)num;
					ExplainedNumber explainedNumber = new ExplainedNumber(0f, true, null);
					ExplainedNumber explainedNumber2 = new ExplainedNumber(0f, true, null);
					ExplainedNumber moraleExplainedNumber = new ExplainedNumber(0f, true, null);
					moraleExplainedNumber = Campaign.Current.Models.BattleRewardModel.CalculateMoraleGainVictory(party2, renownValue, num2);
					mapEventParty2.MoraleChange = moraleExplainedNumber.ResultNumber;
					if (resultExplainers != null && Hero.MainHero == party2.LeaderHero)
					{
						resultExplainers.MoraleExplainedNumber = moraleExplainedNumber;
					}
					if (party2.LeaderHero != null)
					{
						foreach (MobileParty mobileParty in list)
						{
							if (mobileParty.HomeSettlement.OwnerClan != party2.LeaderHero.Clan && !mobileParty.HomeSettlement.OwnerClan.IsEliminated && !party2.LeaderHero.Clan.IsEliminated)
							{
								int num3 = MBRandom.RoundRandomized(4f * num2);
								if (num3 > 0)
								{
									ChangeRelationAction.ApplyRelationChangeBetweenHeroes(mobileParty.HomeSettlement.OwnerClan.Leader, party2.LeaderHero.Clan.Leader, num3, true);
								}
								num3 = MBRandom.RoundRandomized(2f * num2);
								foreach (Hero hero in mobileParty.HomeSettlement.Notables)
								{
									ChangeRelationAction.ApplyRelationChangeBetweenHeroes(hero, party2.LeaderHero.Clan.Leader, num3, true);
								}
							}
						}
						foreach (MobileParty mobileParty2 in list2)
						{
							if (mobileParty2.HomeSettlement != null && mobileParty2.HomeSettlement.OwnerClan != null && party2.LeaderHero != null && mobileParty2.HomeSettlement.OwnerClan.Leader.Clan != party2.LeaderHero.Clan && mobileParty2.Party.Owner != null && mobileParty2.Party.Owner != Hero.MainHero && mobileParty2.Party.Owner.IsAlive && party2.LeaderHero.Clan.Leader != null && party2.LeaderHero.Clan.Leader.IsAlive && !mobileParty2.IsCurrentlyUsedByAQuest)
							{
								int relationChange = MBRandom.RoundRandomized(6f * num2);
								ChangeRelationAction.ApplyRelationChangeBetweenHeroes(mobileParty2.Party.Owner, party2.LeaderHero.Clan.Leader, relationChange, true);
							}
						}
						if (this.MapEvent.IsRaid && this.MissionSide == BattleSideEnum.Defender && this == this.MapEvent.Winner && this.MapEvent.MapEventSettlement.Notables.Any<Hero>())
						{
							ChangeRelationAction.ApplyRelationChangeBetweenHeroes(this.MapEvent.MapEventSettlement.Notables.GetRandomElement<Hero>(), party2.LeaderHero, 5, true);
						}
					}
					if (party2.LeaderHero != null)
					{
						explainedNumber = Campaign.Current.Models.BattleRewardModel.CalculateRenownGain(party2, renownValue, num2);
						explainedNumber2 = Campaign.Current.Models.BattleRewardModel.CalculateInfluenceGain(party2, influenceValue, num2);
						float num4 = this._mapEvent.StrengthOfSide[(int)this.MissionSide.GetOppositeSide()];
						float num5 = num4;
						foreach (MapEventParty mapEventParty3 in this.OtherSide.Parties)
						{
							num5 -= mapEventParty3.Party.TotalStrength;
						}
						mapEventParty2.GainedRenown = explainedNumber.ResultNumber * num5 / num4;
						mapEventParty2.GainedInfluence = explainedNumber2.ResultNumber * num5 / num4;
						if (resultExplainers != null && Hero.MainHero == party2.LeaderHero)
						{
							resultExplainers.RenownExplainedNumber = new ExplainedNumber(mapEventParty2.GainedRenown, false, null);
							resultExplainers.InfluenceExplainedNumber = new ExplainedNumber(mapEventParty2.GainedInfluence, false, null);
						}
					}
				}
			}
			if (!forScoreboard)
			{
				this._mapEvent.RecalculateStrengthOfSides();
				this.CalculateRenownAndInfluenceValues(this._mapEvent.StrengthOfSide);
				return;
			}
			this.RenownAtMapEventEnd = this.RenownValue;
		}

		// Token: 0x0600294D RID: 10573 RVA: 0x000B0838 File Offset: 0x000AEA38
		public void ApplyRenownAndInfluenceChanges()
		{
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				PartyBase party = mapEventParty.Party;
				Hero hero = (party == PartyBase.MainParty) ? Hero.MainHero : party.LeaderHero;
				if (hero != null)
				{
					if (mapEventParty.GainedRenown > 0.001f)
					{
						GainRenownAction.Apply(hero, mapEventParty.GainedRenown, true);
						mapEventParty.GainedRenown = 0f;
					}
					if (mapEventParty.GainedInfluence > 0.001f)
					{
						GainKingdomInfluenceAction.ApplyForBattle(hero, mapEventParty.GainedInfluence);
						mapEventParty.GainedInfluence = 0f;
					}
				}
			}
		}

		// Token: 0x0600294E RID: 10574 RVA: 0x000B08F0 File Offset: 0x000AEAF0
		public void ApplyFinalRewardsAndChanges()
		{
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				PartyBase party = mapEventParty.Party;
				Hero hero = (party == PartyBase.MainParty) ? Hero.MainHero : party.LeaderHero;
				if (party.MobileParty != null)
				{
					party.MobileParty.RecentEventsMorale += mapEventParty.MoraleChange;
				}
				if (hero != null)
				{
					if ((float)mapEventParty.PlunderedGold > 0.001f)
					{
						if (hero == Hero.MainHero)
						{
							MBTextManager.SetTextVariable("GOLD", mapEventParty.PlunderedGold);
							MBInformationManager.AddQuickInformation(GameTexts.FindText("str_plunder_gain_message", null), 0, null, "");
						}
						GiveGoldAction.ApplyBetweenCharacters(null, hero, mapEventParty.PlunderedGold, true);
					}
					if ((float)mapEventParty.GoldLost > 0.001f)
					{
						GiveGoldAction.ApplyBetweenCharacters(hero, null, mapEventParty.GoldLost, true);
					}
				}
				else if (party.IsMobile && party.MobileParty.IsPartyTradeActive)
				{
					party.MobileParty.PartyTradeGold -= mapEventParty.GoldLost;
					party.MobileParty.PartyTradeGold += mapEventParty.PlunderedGold;
				}
			}
		}

		// Token: 0x0600294F RID: 10575 RVA: 0x000B0A3C File Offset: 0x000AEC3C
		public virtual void CalculatePlunderedGoldShare(float totalPlunderedGold, MapEventResultExplainer resultExplainers = null)
		{
			int num = this.CalculateTotalContribution();
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				if (num > 0)
				{
					float num2 = (float)mapEventParty.ContributionToBattle / (float)num;
					num -= mapEventParty.ContributionToBattle;
					int num3 = (int)(num2 * totalPlunderedGold);
					totalPlunderedGold -= (float)num3;
					mapEventParty.PlunderedGold = num3;
				}
			}
		}

		// Token: 0x06002950 RID: 10576 RVA: 0x000B0AB8 File Offset: 0x000AECB8
		public void UpdatePartiesMoveState()
		{
			foreach (MapEventParty mapEventParty in this.Parties)
			{
				if (mapEventParty.Party.IsMobile && mapEventParty.Party.MobileParty.IsActive && mapEventParty.Party.MobileParty.CurrentSettlement == null && ((this._mapEvent.IsRaid && this._mapEvent.MapEventSettlement.SettlementHitPoints <= 0f) || this._mapEvent.IsSiegeAssault) && mapEventParty.Party.MobileParty.Army != null && mapEventParty.Party.MobileParty.Army.AiBehaviorObject == this._mapEvent.MapEventSettlement)
				{
					mapEventParty.Party.MobileParty.Army.AIBehavior = Army.AIBehaviorFlags.Unassigned;
				}
			}
		}

		// Token: 0x06002951 RID: 10577 RVA: 0x000B0BBC File Offset: 0x000AEDBC
		public void HandleMapEventEnd()
		{
			while (this.Parties.Count > 0)
			{
				MapEventParty mapEventParty = this.Parties.FirstOrDefault((MapEventParty x) => !x.Party.IsMobile || x.Party.MobileParty.Army == null || x.Party.MobileParty.Army.LeaderParty != x.Party.MobileParty) ?? this.Parties[this.Parties.Count - 1];
				this.HandleMapEventEndForPartyInternal(mapEventParty.Party);
			}
		}

		// Token: 0x06002952 RID: 10578 RVA: 0x000B0C2C File Offset: 0x000AEE2C
		internal void HandleMapEventEndForPartyInternal(PartyBase party)
		{
			IEnumerable<TroopRosterElement> enumerable = party.MemberRoster.GetTroopRoster().WhereQ((TroopRosterElement x) => x.Character.IsHero && x.Character.HeroObject.IsAlive && x.Character.HeroObject.DeathMark == KillCharacterAction.KillCharacterActionDetail.DiedInBattle);
			PartyBase leaderParty = this._mapEvent.GetLeaderParty(party.OpponentSide);
			bool flag = this._mapEvent.IsWinnerSide(party.Side);
			bool attackersRanAway = this._mapEvent.AttackersRanAway;
			party.MapEventSide = null;
			foreach (TroopRosterElement troopRosterElement in enumerable)
			{
				KillCharacterAction.ApplyByBattle(troopRosterElement.Character.HeroObject, this.OtherSide.LeaderParty.LeaderHero, true);
			}
			if (party.IsMobile && (party.NumberOfAllMembers == 0 || (!flag && !attackersRanAway && (party.NumberOfHealthyMembers == 0 || (this._mapEvent.BattleState != BattleState.None && party.MobileParty.IsMilitia)) && (party.MobileParty.Army == null || party.MobileParty.Army.LeaderParty.Party.NumberOfHealthyMembers == 0))) && party != PartyBase.MainParty && party.IsActive && (!party.MobileParty.IsDisbanding || party.MemberRoster.Count == 0))
			{
				DestroyPartyAction.Apply(leaderParty, party.MobileParty);
			}
			party.MemberRoster.RemoveZeroCounts();
			party.PrisonRoster.RemoveZeroCounts();
			if (party.IsMobile && party.MobileParty.IsActive && party.MobileParty.CurrentSettlement == null)
			{
				party.SetVisualAsDirty();
			}
		}

		// Token: 0x06002953 RID: 10579 RVA: 0x000B0DD0 File Offset: 0x000AEFD0
		public void AddHeroDamage(Hero character, int damage)
		{
			character.HitPoints -= damage;
		}

		// Token: 0x06002954 RID: 10580 RVA: 0x000B0DE0 File Offset: 0x000AEFE0
		public void AllocateTroops(ref List<UniqueTroopDescriptor> troopsList, int number = -1, Func<UniqueTroopDescriptor, MapEventParty, bool> customAllocationConditions = null)
		{
			if (troopsList == null)
			{
				troopsList = new List<UniqueTroopDescriptor>();
			}
			else
			{
				troopsList.Clear();
			}
			int k = (number >= 0) ? number : 100000000;
			while (k > 0)
			{
				int num = -1;
				float num2 = float.MinValue;
				for (int j = 0; j < this._readyTroopsPriorityList.Count; j++)
				{
					if (this._readyTroopsPriorityList[j].Item3 > num2)
					{
						num2 = this._readyTroopsPriorityList[j].Item3;
						num = j;
					}
				}
				if (num == -1)
				{
					break;
				}
				ValueTuple<FlattenedTroopRosterElement, MapEventParty, float> valueTuple = this._readyTroopsPriorityList[num];
				UniqueTroopDescriptor descriptor = valueTuple.Item1.Descriptor;
				MapEventParty item = valueTuple.Item2;
				this._readyTroopsPriorityList[num] = new ValueTuple<FlattenedTroopRosterElement, MapEventParty, float>(FlattenedTroopRosterElement.DefaultFlattenedTroopRosterElement, null, float.MinValue);
				if (customAllocationConditions == null || customAllocationConditions(descriptor, item))
				{
					troopsList.Add(descriptor);
					this._allocatedTroops.Add(descriptor, item);
					k--;
					if (this.BattleObserver != null)
					{
						this.BattleObserver.TroopNumberChanged(this.MissionSide, item.Party, item.Troops[descriptor].Troop, 1, 0, 0, 0, 0, 0);
						if (this._troopUpgradeTracker == null)
						{
							this._troopUpgradeTracker = new TroopUpgradeTracker();
						}
						this._troopUpgradeTracker.AddTrackedTroop(item.Party, item.Troops[descriptor].Troop);
					}
				}
			}
			this._readyTroopsPriorityList.RemoveAll((ValueTuple<FlattenedTroopRosterElement, MapEventParty, float> i) => i.Item3 <= float.MinValue);
			this._requiresTroopCacheUpdate = true;
		}

		// Token: 0x06002955 RID: 10581 RVA: 0x000B0F88 File Offset: 0x000AF188
		public void GetAllTroops(ref List<UniqueTroopDescriptor> troopsList)
		{
			if (troopsList == null)
			{
				troopsList = new List<UniqueTroopDescriptor>();
			}
			else
			{
				troopsList.Clear();
			}
			foreach (ValueTuple<FlattenedTroopRosterElement, MapEventParty, float> valueTuple in this._readyTroopsPriorityList)
			{
				List<UniqueTroopDescriptor> list = troopsList;
				FlattenedTroopRosterElement item = valueTuple.Item1;
				list.Add(item.Descriptor);
			}
			foreach (UniqueTroopDescriptor item2 in this._allocatedTroops.Keys)
			{
				troopsList.Add(item2);
			}
		}

		// Token: 0x06002956 RID: 10582 RVA: 0x000B1048 File Offset: 0x000AF248
		public CharacterObject GetAllocatedTroop(UniqueTroopDescriptor troopDesc0)
		{
			MapEventParty mapEventParty;
			if (this._allocatedTroops.TryGetValue(troopDesc0, out mapEventParty))
			{
				return mapEventParty.Troops[troopDesc0].Troop;
			}
			return null;
		}

		// Token: 0x06002957 RID: 10583 RVA: 0x000B107C File Offset: 0x000AF27C
		public CharacterObject GetReadyTroop(UniqueTroopDescriptor troopDesc0)
		{
			this.CheckReadyTroopsTemporaryCache();
			MapEventParty mapEventParty;
			if (this._readyTroopsTemporaryCache.TryGetValue(troopDesc0, out mapEventParty))
			{
				return mapEventParty.Troops[troopDesc0].Troop;
			}
			return null;
		}

		// Token: 0x06002958 RID: 10584 RVA: 0x000B10B8 File Offset: 0x000AF2B8
		public PartyBase GetAllocatedTroopParty(UniqueTroopDescriptor troopDescriptor)
		{
			MapEventParty mapEventParty;
			if (this._allocatedTroops.TryGetValue(troopDescriptor, out mapEventParty))
			{
				return mapEventParty.Party;
			}
			return null;
		}

		// Token: 0x06002959 RID: 10585 RVA: 0x000B10E0 File Offset: 0x000AF2E0
		public PartyBase GetReadyTroopParty(UniqueTroopDescriptor troopDescriptor)
		{
			this.CheckReadyTroopsTemporaryCache();
			MapEventParty mapEventParty;
			if (this._readyTroopsTemporaryCache.TryGetValue(troopDescriptor, out mapEventParty))
			{
				return mapEventParty.Party;
			}
			return null;
		}

		// Token: 0x0600295A RID: 10586 RVA: 0x000B110C File Offset: 0x000AF30C
		public void OnTroopWounded(UniqueTroopDescriptor troopDesc1)
		{
			MapEventParty mapEventParty = this._allocatedTroops[troopDesc1];
			mapEventParty.OnTroopWounded(troopDesc1);
			CharacterObject troop = mapEventParty.GetTroop(troopDesc1);
			float troopPower = Campaign.Current.Models.MilitaryPowerModel.GetTroopPower(troop, this.MissionSide, this.MapEvent.SimulationContext, this.LeaderSimulationModifier);
			this.CasualtyStrength += troopPower;
			this.Casualties++;
		}

		// Token: 0x0600295B RID: 10587 RVA: 0x000B117C File Offset: 0x000AF37C
		public void OnTroopKilled(UniqueTroopDescriptor troopDesc1)
		{
			MapEventParty mapEventParty = this._allocatedTroops[troopDesc1];
			mapEventParty.OnTroopKilled(troopDesc1);
			CharacterObject troop = mapEventParty.GetTroop(troopDesc1);
			float troopPower = Campaign.Current.Models.MilitaryPowerModel.GetTroopPower(troop, this.MissionSide, this.MapEvent.SimulationContext, this.LeaderSimulationModifier);
			this.CasualtyStrength += troopPower;
			this.Casualties++;
		}

		// Token: 0x0600295C RID: 10588 RVA: 0x000B11EC File Offset: 0x000AF3EC
		public void OnTroopRouted(UniqueTroopDescriptor troopDesc1)
		{
			MapEventParty mapEventParty = this._allocatedTroops[troopDesc1];
			mapEventParty.OnTroopRouted(troopDesc1);
			CharacterObject troop = mapEventParty.GetTroop(troopDesc1);
			float troopPower = Campaign.Current.Models.MilitaryPowerModel.GetTroopPower(troop, this.MissionSide, this.MapEvent.SimulationContext, this.LeaderSimulationModifier);
			this.CasualtyStrength += troopPower * 0.1f;
		}

		// Token: 0x0600295D RID: 10589 RVA: 0x000B1254 File Offset: 0x000AF454
		public void OnTroopScoreHit(UniqueTroopDescriptor troopDesc1, CharacterObject attackedTroop, int damage, bool isFatal, bool isTeamKill, WeaponComponentData attackerWeapon, bool isSimulatedHit)
		{
			this._allocatedTroops[troopDesc1].OnTroopScoreHit(troopDesc1, attackedTroop, damage, isFatal, isTeamKill, attackerWeapon, isSimulatedHit);
		}

		// Token: 0x0600295E RID: 10590 RVA: 0x000B1274 File Offset: 0x000AF474
		private void MakeReady(bool includeHumanPlayers, FlattenedTroopRoster priorTroops = null, int sizeOfSide = -1)
		{
			if (this._readyTroopsPriorityList == null || this._allocatedTroops == null)
			{
				this._readyTroopsPriorityList = new List<ValueTuple<FlattenedTroopRosterElement, MapEventParty, float>>();
				this._allocatedTroops = new Dictionary<UniqueTroopDescriptor, MapEventParty>();
			}
			else
			{
				this._readyTroopsPriorityList.Clear();
				this._allocatedTroops.Clear();
			}
			if (sizeOfSide <= 0)
			{
				sizeOfSide = 0;
				foreach (MapEventParty mapEventParty in this._battleParties)
				{
					sizeOfSide += mapEventParty.Party.NumberOfHealthyMembers;
				}
			}
			foreach (MapEventParty battleParty in this._battleParties)
			{
				this.MakeReadyParty(battleParty, priorTroops, includeHumanPlayers, sizeOfSide);
			}
			this._requiresTroopCacheUpdate = true;
		}

		// Token: 0x0600295F RID: 10591 RVA: 0x000B1360 File Offset: 0x000AF560
		private void MakeReadyParty(MapEventParty battleParty, FlattenedTroopRoster priorityTroops, bool includePlayers, int sizeOfSide)
		{
			battleParty.Update();
			bool forcePriorityTroops = priorityTroops != null && this._mapEvent.PlayerSide == this.MissionSide && (this._mapEvent.IsHideoutBattle || (this._mapEvent.IsSiegeAssault && PlayerSiege.BesiegedSettlement != null && PlayerSiege.BesiegedSettlement.CurrentSiegeState == Settlement.SiegeState.InTheLordsHall));
			Campaign.Current.Models.TroopSupplierProbabilityModel.EnqueueTroopSpawnProbabilitiesAccordingToUnitSpawnPrioritization(battleParty, priorityTroops, includePlayers, sizeOfSide, forcePriorityTroops, this._readyTroopsPriorityList);
		}

		// Token: 0x06002960 RID: 10592 RVA: 0x000B13E4 File Offset: 0x000AF5E4
		private void CheckReadyTroopsTemporaryCache()
		{
			if (this._readyTroopsTemporaryCache == null)
			{
				this._readyTroopsTemporaryCache = new Dictionary<UniqueTroopDescriptor, MapEventParty>();
			}
			if (this._requiresTroopCacheUpdate)
			{
				this._readyTroopsTemporaryCache.Clear();
				foreach (ValueTuple<FlattenedTroopRosterElement, MapEventParty, float> valueTuple in this._readyTroopsPriorityList)
				{
					Dictionary<UniqueTroopDescriptor, MapEventParty> readyTroopsTemporaryCache = this._readyTroopsTemporaryCache;
					FlattenedTroopRosterElement item = valueTuple.Item1;
					readyTroopsTemporaryCache.Add(item.Descriptor, valueTuple.Item2);
				}
				this._requiresTroopCacheUpdate = false;
			}
		}

		// Token: 0x06002961 RID: 10593 RVA: 0x000B147C File Offset: 0x000AF67C
		public void MakeReadyForSimulation(FlattenedTroopRoster priorTroops, int sizeOfSide = -1)
		{
			this.MakeReady(false, priorTroops, sizeOfSide);
			this.AllocateTroops(ref this._simulationTroopList, sizeOfSide, null);
		}

		// Token: 0x06002962 RID: 10594 RVA: 0x000B1495 File Offset: 0x000AF695
		public void MakeReadyForMission(FlattenedTroopRoster priorTroops)
		{
			this.MakeReady(true, priorTroops, -1);
		}

		// Token: 0x06002963 RID: 10595 RVA: 0x000B14A0 File Offset: 0x000AF6A0
		public void EndSimulation()
		{
			this._simulationTroopList.Clear();
			this._readyTroopsPriorityList.Clear();
			this._requiresTroopCacheUpdate = true;
			this._allocatedTroops.Clear();
		}

		// Token: 0x06002964 RID: 10596 RVA: 0x000B14CC File Offset: 0x000AF6CC
		internal void ResetContributionToBattleToStrength()
		{
			foreach (MapEventParty mapEventParty in this._battleParties)
			{
				mapEventParty.ResetContributionToBattleToStrength();
			}
		}

		// Token: 0x06002965 RID: 10597 RVA: 0x000B151C File Offset: 0x000AF71C
		internal void CollectAll(LootCollector lootCollector, out bool playerCaptured)
		{
			playerCaptured = false;
			bool flag = false;
			ExplainedNumber explainedNumber = new ExplainedNumber(1f, false, null);
			float num = 0f;
			foreach (MapEventParty mapEventParty in this.OtherSide.Parties)
			{
				if (mapEventParty != null)
				{
					PartyBase party = mapEventParty.Party;
					bool? flag2;
					if (party == null)
					{
						flag2 = null;
					}
					else
					{
						MobileParty mobileParty = party.MobileParty;
						flag2 = ((mobileParty != null) ? new bool?(mobileParty.HasPerk(DefaultPerks.Roguery.KnowHow, false)) : null);
					}
					bool? flag3 = flag2;
					bool flag4 = true;
					if (flag3.GetValueOrDefault() == flag4 & flag3 != null)
					{
						flag = true;
					}
				}
				bool flag5;
				if (mapEventParty == null)
				{
					flag5 = (null != null);
				}
				else
				{
					PartyBase party2 = mapEventParty.Party;
					flag5 = (((party2 != null) ? party2.LeaderHero : null) != null);
				}
				if (flag5 && mapEventParty.Party.LeaderHero.GetPerkValue(DefaultPerks.Roguery.RogueExtraordinaire) && num < (float)mapEventParty.Party.LeaderHero.GetSkillValue(DefaultSkills.Roguery))
				{
					num = (float)mapEventParty.Party.LeaderHero.GetSkillValue(DefaultSkills.Roguery);
					PerkHelper.AddEpicPerkBonusForCharacter(DefaultPerks.Roguery.RogueExtraordinaire, mapEventParty.Party.LeaderHero.CharacterObject, DefaultSkills.Roguery, true, ref explainedNumber, Campaign.Current.Models.CharacterDevelopmentModel.MinSkillRequiredForEpicPerkBonus);
				}
			}
			foreach (MapEventParty mapEventParty2 in this._battleParties)
			{
				PartyBase party3 = mapEventParty2.Party;
				MapEventSide.CaptureWoundedTroops(lootCollector, party3, this.IsSurrendered, ref playerCaptured);
				lootCollector.LootedPrisoners.Add(party3.PrisonRoster);
				bool flag6 = false;
				for (int i = party3.PrisonRoster.Count - 1; i >= 0; i--)
				{
					TroopRosterElement troopRosterElement = party3.PrisonRoster.data[i];
					if (!troopRosterElement.Character.IsHero)
					{
						party3.PrisonRoster.RemoveTroop(troopRosterElement.Character, troopRosterElement.Number, default(UniqueTroopDescriptor), 0);
						flag6 = true;
					}
				}
				if (flag6)
				{
					party3.PrisonRoster.RemoveZeroCounts();
				}
				float num2 = 0.5f;
				num2 *= explainedNumber.ResultNumber;
				if (party3.IsMobile)
				{
					if (flag && (party3.MobileParty.IsCaravan || party3.MobileParty.IsVillager))
					{
						num2 *= 1f + DefaultPerks.Roguery.KnowHow.PrimaryBonus;
					}
				}
				else if (party3.IsSettlement)
				{
					Settlement settlement = party3.Settlement;
					if (settlement.IsTown)
					{
						num2 = 0f;
					}
					else if (settlement.IsVillage)
					{
						num2 = ((settlement.SettlementHitPoints > 0f) ? 0f : 1f);
					}
					else
					{
						num2 = 1f;
					}
				}
				num2 = ((1f > num2) ? num2 : 1f);
				if (party3 == PartyBase.MainParty)
				{
					MBList<ItemRosterElement> mblist = (from x in party3.ItemRoster
					where x.EquipmentElement.Item.IsMountable
					select x).ToMBList<ItemRosterElement>();
					mblist.Shuffle<ItemRosterElement>();
					Dictionary<ItemRosterElement, int> dictionary = new Dictionary<ItemRosterElement, int>();
					int num3 = 0;
					foreach (ItemRosterElement key in mblist)
					{
						int num4 = MathF.Min(key.Amount, 3 - num3);
						dictionary.Add(key, num4);
						num3 += num4;
						if (num3 == 3)
						{
							break;
						}
					}
					ItemRoster itemRoster = new ItemRoster(party3.ItemRoster);
					for (int j = 0; j < itemRoster.Count; j++)
					{
						ItemRosterElement key2 = itemRoster[j];
						if (!key2.EquipmentElement.Item.NotMerchandise && !key2.EquipmentElement.IsQuestItem && !key2.EquipmentElement.Item.IsBannerItem)
						{
							int num5;
							dictionary.TryGetValue(key2, out num5);
							int num6 = key2.Amount - num5;
							if (num6 > 0)
							{
								int number = MBRandom.RoundRandomized((float)num6 * num2);
								lootCollector.AddLootedItems(party3, key2.EquipmentElement, number);
								party3.ItemRoster.AddToCounts(key2.EquipmentElement, -num6);
							}
						}
					}
				}
				else
				{
					ItemRoster itemRoster2 = new ItemRoster(party3.ItemRoster);
					for (int k = 0; k < itemRoster2.Count; k++)
					{
						ItemRosterElement itemRosterElement = itemRoster2[k];
						if (!itemRosterElement.EquipmentElement.Item.NotMerchandise && !itemRosterElement.EquipmentElement.IsQuestItem)
						{
							int num7 = MBRandom.RoundRandomized((float)itemRosterElement.Amount * num2 * (itemRosterElement.EquipmentElement.Item.IsMountable ? 0.33f : 1f));
							if (num7 > 0)
							{
								lootCollector.AddLootedItems(party3, itemRosterElement.EquipmentElement, num7);
								party3.ItemRoster.AddToCounts(itemRosterElement.EquipmentElement, -num7);
							}
						}
					}
				}
				lootCollector.CasualtiesInBattle.Add(mapEventParty2.DiedInBattle);
				lootCollector.CasualtiesInBattle.Add(mapEventParty2.WoundedInBattle);
				MapEventSide.OnPartyDefeated(party3);
			}
		}

		// Token: 0x06002966 RID: 10598 RVA: 0x000B1AB8 File Offset: 0x000AFCB8
		private static void OnPartyDefeated(PartyBase defeatedParty)
		{
			if (!defeatedParty.IsMobile)
			{
				return;
			}
			defeatedParty.MobileParty.RecentEventsMorale += Campaign.Current.Models.PartyMoraleModel.GetDefeatMoraleChange(defeatedParty);
			if (defeatedParty.NumberOfHealthyMembers > 0 && (!defeatedParty.IsMobile || !defeatedParty.MobileParty.IsGarrison))
			{
				if (defeatedParty.MobileParty.CurrentSettlement != null)
				{
					defeatedParty.MobileParty.Position2D = defeatedParty.MobileParty.CurrentSettlement.GatePosition;
				}
				else
				{
					defeatedParty.MobileParty.Position2D = MobilePartyHelper.FindReachablePointAroundPosition(defeatedParty.MobileParty.Position2D, 4f, 3f);
				}
				defeatedParty.MobileParty.Ai.ForceDefaultBehaviorUpdate();
			}
		}

		// Token: 0x06002967 RID: 10599 RVA: 0x000B1B74 File Offset: 0x000AFD74
		private static void CaptureWoundedTroops(LootCollector lootCollector, PartyBase defeatedParty, bool isSurrender, ref bool playerCaptured)
		{
			MapEventSide.CaptureRegularTroops(lootCollector, defeatedParty, isSurrender);
			if (defeatedParty == PartyBase.MainParty)
			{
				bool flag;
				MapEventSide.CaptureWoundedHeroesForMainParty(lootCollector, defeatedParty, isSurrender, out flag);
				if (flag)
				{
					playerCaptured = true;
				}
			}
			else if (defeatedParty.LeaderHero != null)
			{
				MapEventSide.CaptureWoundedHeroes(lootCollector, defeatedParty, isSurrender);
			}
			defeatedParty.MemberRoster.RemoveZeroCounts();
		}

		// Token: 0x06002968 RID: 10600 RVA: 0x000B1BC0 File Offset: 0x000AFDC0
		private static void CaptureWoundedHeroesForMainParty(LootCollector lootCollector, PartyBase defeatedParty, bool isSurrender, out bool playerCaptured)
		{
			playerCaptured = false;
			bool flag = false;
			if (defeatedParty != PartyBase.MainParty)
			{
				foreach (TroopRosterElement troopRosterElement in defeatedParty.MemberRoster.GetTroopRoster())
				{
					if (troopRosterElement.Character != null && troopRosterElement.Character.IsHero && !troopRosterElement.Character.HeroObject.IsWounded)
					{
						flag = true;
					}
				}
			}
			if (!flag || isSurrender)
			{
				playerCaptured = true;
				for (int i = 0; i < defeatedParty.MemberRoster.Count; i++)
				{
					TroopRosterElement elementCopyAtIndex = defeatedParty.MemberRoster.GetElementCopyAtIndex(i);
					if (elementCopyAtIndex.Character.IsHero)
					{
						if (elementCopyAtIndex.Character.HeroObject.DeathMark != KillCharacterAction.KillCharacterActionDetail.DiedInBattle)
						{
							defeatedParty.MemberRoster.AddToCountsAtIndex(i, -1, 0, 0, false);
							if (elementCopyAtIndex.Character.HeroObject != Hero.MainHero && MBRandom.RandomFloat < 0.5f)
							{
								MakeHeroFugitiveAction.Apply(elementCopyAtIndex.Character.HeroObject);
							}
							else if (!elementCopyAtIndex.Character.HeroObject.IsDead && elementCopyAtIndex.Character.HeroObject.DeathMark == KillCharacterAction.KillCharacterActionDetail.None)
							{
								lootCollector.LootedMembers.AddToCounts(elementCopyAtIndex.Character, 1, false, 0, 0, true, -1);
							}
							if (defeatedParty.LeaderHero == elementCopyAtIndex.Character.HeroObject && defeatedParty.IsMobile)
							{
								defeatedParty.MobileParty.RemovePartyLeader();
							}
						}
					}
					else if (elementCopyAtIndex.Number > 0)
					{
						defeatedParty.MemberRoster.AddToCountsAtIndex(i, -elementCopyAtIndex.Number, 0, 0, false);
						lootCollector.LootedMembers.AddToCounts(elementCopyAtIndex.Character, elementCopyAtIndex.Number, false, 0, 0, true, -1);
					}
				}
			}
		}

		// Token: 0x06002969 RID: 10601 RVA: 0x000B1D94 File Offset: 0x000AFF94
		private static void CaptureRegularTroops(LootCollector lootCollector, PartyBase defeatedParty, bool isSurrender)
		{
			for (int i = 0; i < defeatedParty.MemberRoster.Count; i++)
			{
				TroopRosterElement elementCopyAtIndex = defeatedParty.MemberRoster.GetElementCopyAtIndex(i);
				if (!elementCopyAtIndex.Character.IsHero && (elementCopyAtIndex.WoundedNumber > 0 || (isSurrender && elementCopyAtIndex.Number > 0)))
				{
					int num = isSurrender ? elementCopyAtIndex.Number : elementCopyAtIndex.WoundedNumber;
					lootCollector.LootedMembers.AddToCounts(elementCopyAtIndex.Character, num, false, 0, 0, true, -1);
					defeatedParty.MemberRoster.AddToCountsAtIndex(i, -num, -elementCopyAtIndex.WoundedNumber, 0, false);
				}
			}
		}

		// Token: 0x0600296A RID: 10602 RVA: 0x000B1E30 File Offset: 0x000B0030
		private static void CaptureWoundedHeroes(LootCollector lootCollector, PartyBase defeatedParty, bool isSurrender)
		{
			if (defeatedParty.LeaderHero.IsWounded || isSurrender)
			{
				for (int i = 0; i < defeatedParty.MemberRoster.Count; i++)
				{
					TroopRosterElement elementCopyAtIndex = defeatedParty.MemberRoster.GetElementCopyAtIndex(i);
					if (elementCopyAtIndex.Character.IsHero)
					{
						if (elementCopyAtIndex.Character.HeroObject.DeathMark != KillCharacterAction.KillCharacterActionDetail.DiedInBattle)
						{
							lootCollector.LootedMembers.AddToCounts(elementCopyAtIndex.Character, 1, false, 0, 0, true, -1);
							if (defeatedParty.LeaderHero == elementCopyAtIndex.Character.HeroObject && defeatedParty.IsMobile)
							{
								defeatedParty.MobileParty.RemovePartyLeader();
							}
							defeatedParty.MemberRoster.AddToCountsAtIndex(i, -1, 0, 0, false);
						}
					}
					else if (elementCopyAtIndex.Number > 0)
					{
						lootCollector.LootedMembers.AddToCounts(elementCopyAtIndex.Character, elementCopyAtIndex.Number, false, 0, 0, true, -1);
						defeatedParty.MemberRoster.AddToCountsAtIndex(i, -elementCopyAtIndex.Number, 0, 0, false);
					}
				}
			}
		}

		// Token: 0x0600296B RID: 10603 RVA: 0x000B1F2C File Offset: 0x000B012C
		public ItemRoster ItemRosterForPlayerLootShare(PartyBase playerParty)
		{
			int index = this._battleParties.FindIndexQ((MapEventParty p) => p.Party == playerParty);
			return this._battleParties[index].RosterToReceiveLootItems;
		}

		// Token: 0x0600296C RID: 10604 RVA: 0x000B1F70 File Offset: 0x000B0170
		public TroopRoster MemberRosterForPlayerLootShare(PartyBase playerParty)
		{
			int index = this._battleParties.FindIndexQ((MapEventParty p) => p.Party == playerParty);
			return this._battleParties[index].RosterToReceiveLootMembers;
		}

		// Token: 0x0600296D RID: 10605 RVA: 0x000B1FB4 File Offset: 0x000B01B4
		public TroopRoster PrisonerRosterForPlayerLootShare(PartyBase playerParty)
		{
			int index = this._battleParties.FindIndexQ((MapEventParty p) => p.Party == playerParty);
			return this._battleParties[index].RosterToReceiveLootPrisoners;
		}

		// Token: 0x0600296E RID: 10606 RVA: 0x000B1FF7 File Offset: 0x000B01F7
		public void Clear()
		{
			this._battleParties.Clear();
		}

		// Token: 0x0600296F RID: 10607 RVA: 0x000B2004 File Offset: 0x000B0204
		public UniqueTroopDescriptor SelectRandomSimulationTroop()
		{
			this._selectedSimulationTroopIndex = MBRandom.RandomInt(this.NumRemainingSimulationTroops);
			this._selectedSimulationTroopDescriptor = this._simulationTroopList[this._selectedSimulationTroopIndex];
			this._selectedSimulationTroop = this.GetAllocatedTroop(this._selectedSimulationTroopDescriptor);
			return this._selectedSimulationTroopDescriptor;
		}

		// Token: 0x06002970 RID: 10608 RVA: 0x000B2054 File Offset: 0x000B0254
		private void RemoveSelectedTroopFromSimulationList()
		{
			this._simulationTroopList[this._selectedSimulationTroopIndex] = this._simulationTroopList[this._simulationTroopList.Count - 1];
			this._simulationTroopList.RemoveAt(this._simulationTroopList.Count - 1);
			this._selectedSimulationTroopIndex = -1;
			this._selectedSimulationTroopDescriptor = UniqueTroopDescriptor.Invalid;
			this._selectedSimulationTroop = null;
		}

		// Token: 0x06002971 RID: 10609 RVA: 0x000B20BC File Offset: 0x000B02BC
		internal bool ApplySimulationDamageToSelectedTroop(int damage, DamageTypes damageType, PartyBase strikerParty)
		{
			bool flag = false;
			if (this._selectedSimulationTroop.IsHero)
			{
				this.AddHeroDamage(this._selectedSimulationTroop.HeroObject, damage);
				if (this._selectedSimulationTroop.HeroObject.IsWounded)
				{
					PartyHealingModel partyHealingModel = Campaign.Current.Models.PartyHealingModel;
					MobileParty partyBelongedTo = this._selectedSimulationTroop.HeroObject.PartyBelongedTo;
					float survivalChance = partyHealingModel.GetSurvivalChance(((partyBelongedTo != null) ? partyBelongedTo.Party : null) ?? null, this._selectedSimulationTroop, damageType, false, strikerParty);
					if (MBRandom.RandomFloat > survivalChance && this._selectedSimulationTroop.HeroObject.CanDie(KillCharacterAction.KillCharacterActionDetail.DiedInBattle))
					{
						this.OnTroopKilled(this._selectedSimulationTroopDescriptor);
						IBattleObserver battleObserver = this.BattleObserver;
						if (battleObserver != null)
						{
							battleObserver.TroopNumberChanged(this.MissionSide, this.GetAllocatedTroopParty(this._selectedSimulationTroopDescriptor), this._selectedSimulationTroop, -1, 1, 0, 0, 0, 0);
						}
						KillCharacterAction.ApplyByBattle(this._selectedSimulationTroop.HeroObject, null, false);
					}
					else
					{
						this.OnTroopWounded(this._selectedSimulationTroopDescriptor);
						IBattleObserver battleObserver2 = this.BattleObserver;
						if (battleObserver2 != null)
						{
							battleObserver2.TroopNumberChanged(this.MissionSide, this.GetAllocatedTroopParty(this._selectedSimulationTroopDescriptor), this._selectedSimulationTroop, -1, 0, 1, 0, 0, 0);
						}
					}
					flag = true;
				}
			}
			else if (MBRandom.RandomInt(this._selectedSimulationTroop.MaxHitPoints()) < damage)
			{
				PartyBase party = this._allocatedTroops[this._selectedSimulationTroopDescriptor].Party;
				float survivalChance2 = Campaign.Current.Models.PartyHealingModel.GetSurvivalChance(party, this._selectedSimulationTroop, damageType, false, strikerParty);
				if (MBRandom.RandomFloat < survivalChance2)
				{
					this.OnTroopWounded(this._selectedSimulationTroopDescriptor);
					IBattleObserver battleObserver3 = this.BattleObserver;
					if (battleObserver3 != null)
					{
						battleObserver3.TroopNumberChanged(this.MissionSide, this.GetAllocatedTroopParty(this._selectedSimulationTroopDescriptor), this._selectedSimulationTroop, -1, 0, 1, 0, 0, 0);
					}
					SkillLevelingManager.OnSurgeryApplied(party.MobileParty, true, this._selectedSimulationTroop.Tier);
					if (((strikerParty != null) ? strikerParty.MobileParty : null) != null && strikerParty.MobileParty.HasPerk(DefaultPerks.Medicine.DoctorsOath, false))
					{
						SkillLevelingManager.OnSurgeryApplied(strikerParty.MobileParty, true, this._selectedSimulationTroop.Tier);
					}
				}
				else
				{
					this.OnTroopKilled(this._selectedSimulationTroopDescriptor);
					IBattleObserver battleObserver4 = this.BattleObserver;
					if (battleObserver4 != null)
					{
						battleObserver4.TroopNumberChanged(this.MissionSide, this.GetAllocatedTroopParty(this._selectedSimulationTroopDescriptor), this._selectedSimulationTroop, -1, 1, 0, 0, 0, 0);
					}
					SkillLevelingManager.OnSurgeryApplied(party.MobileParty, false, this._selectedSimulationTroop.Tier);
					if (((strikerParty != null) ? strikerParty.MobileParty : null) != null && strikerParty.MobileParty.HasPerk(DefaultPerks.Medicine.DoctorsOath, false))
					{
						SkillLevelingManager.OnSurgeryApplied(strikerParty.MobileParty, false, this._selectedSimulationTroop.Tier);
					}
				}
				flag = true;
			}
			if (flag)
			{
				this.RemoveSelectedTroopFromSimulationList();
			}
			return flag;
		}

		// Token: 0x06002972 RID: 10610 RVA: 0x000B2370 File Offset: 0x000B0570
		public void ApplySimulatedHitRewardToSelectedTroop(CharacterObject strikerTroop, CharacterObject attackedTroop, int damage, bool isFinishingStrike)
		{
			EquipmentElement equipmentElement = strikerTroop.FirstBattleEquipment[EquipmentIndex.WeaponItemBeginSlot];
			UniqueTroopDescriptor selectedSimulationTroopDescriptor = this._selectedSimulationTroopDescriptor;
			bool isTeamKill = false;
			ItemObject item = equipmentElement.Item;
			this.OnTroopScoreHit(selectedSimulationTroopDescriptor, attackedTroop, damage, isFinishingStrike, isTeamKill, (item != null) ? item.PrimaryWeapon : null, true);
			PartyBase party = this._allocatedTroops[this._selectedSimulationTroopDescriptor].Party;
			if (isFinishingStrike && (!attackedTroop.IsHero || !attackedTroop.HeroObject.IsDead))
			{
				SkillLevelingManager.OnSimulationCombatKill(this._selectedSimulationTroop, attackedTroop, party, this.LeaderParty);
			}
			if (this.BattleObserver != null)
			{
				if (isFinishingStrike)
				{
					this.BattleObserver.TroopNumberChanged(this.MissionSide, party, this._selectedSimulationTroop, 0, 0, 0, 0, 1, 0);
				}
				if (this._selectedSimulationTroop.IsHero)
				{
					using (List<SkillObject>.Enumerator enumerator = this._troopUpgradeTracker.CheckSkillUpgrades(this._selectedSimulationTroop.HeroObject).ToList<SkillObject>().GetEnumerator())
					{
						while (enumerator.MoveNext())
						{
							SkillObject skill = enumerator.Current;
							this.BattleObserver.HeroSkillIncreased(this.MissionSide, party, this._selectedSimulationTroop, skill);
						}
						return;
					}
				}
				int num = this._troopUpgradeTracker.CheckUpgradedCount(party, this._selectedSimulationTroop);
				if (num != 0)
				{
					this.BattleObserver.TroopNumberChanged(this.MissionSide, party, this._selectedSimulationTroop, 0, 0, 0, 0, 0, num);
				}
			}
		}

		// Token: 0x06002973 RID: 10611 RVA: 0x000B24D0 File Offset: 0x000B06D0
		public void Surrender()
		{
			MapEventSide.SurrenderParty(this.LeaderParty);
			this.IsSurrendered = true;
		}

		// Token: 0x06002974 RID: 10612 RVA: 0x000B24E4 File Offset: 0x000B06E4
		private static void SurrenderParty(PartyBase party)
		{
			for (int i = 0; i < party.MemberRoster.Count; i++)
			{
				TroopRosterElement elementCopyAtIndex = party.MemberRoster.GetElementCopyAtIndex(i);
				if (!elementCopyAtIndex.Character.IsHero)
				{
					party.MemberRoster.AddToCountsAtIndex(i, 0, elementCopyAtIndex.Number - elementCopyAtIndex.WoundedNumber, 0, true);
				}
			}
		}

		// Token: 0x06002975 RID: 10613 RVA: 0x000B2540 File Offset: 0x000B0740
		internal void AddNearbyPartyToPlayerMapEvent(MobileParty party)
		{
			if (party.MapEventSide != this)
			{
				party.MapEventSide = this;
				this._nearbyPartiesAddedToPlayerMapEvent.Add(party);
				CampaignEventDispatcher.Instance.OnNearbyPartyAddedToPlayerMapEvent(party);
			}
		}

		// Token: 0x06002976 RID: 10614 RVA: 0x000B256C File Offset: 0x000B076C
		internal void RemoveNearbyPartiesFromPlayerMapEvent()
		{
			foreach (MobileParty mobileParty in this._nearbyPartiesAddedToPlayerMapEvent)
			{
				mobileParty.MapEventSide = null;
			}
			this._nearbyPartiesAddedToPlayerMapEvent.Clear();
		}

		// Token: 0x04000C6E RID: 3182
		[CachedData]
		private List<ValueTuple<FlattenedTroopRosterElement, MapEventParty, float>> _readyTroopsPriorityList;

		// Token: 0x04000C6F RID: 3183
		[CachedData]
		private Dictionary<UniqueTroopDescriptor, MapEventParty> _readyTroopsTemporaryCache;

		// Token: 0x04000C70 RID: 3184
		[CachedData]
		private bool _requiresTroopCacheUpdate;

		// Token: 0x04000C71 RID: 3185
		[CachedData]
		private Dictionary<UniqueTroopDescriptor, MapEventParty> _allocatedTroops;

		// Token: 0x04000C72 RID: 3186
		[CachedData]
		internal float LeaderSimulationModifier;

		// Token: 0x04000C74 RID: 3188
		[SaveableField(30)]
		private readonly MBList<MapEventParty> _battleParties;

		// Token: 0x04000C76 RID: 3190
		[SaveableField(9)]
		public float StrengthRatio = 1f;

		// Token: 0x04000C77 RID: 3191
		[SaveableField(10)]
		public float RenownValue;

		// Token: 0x04000C78 RID: 3192
		[SaveableField(11)]
		public float InfluenceValue;

		// Token: 0x04000C79 RID: 3193
		public float RenownAtMapEventEnd;

		// Token: 0x04000C7A RID: 3194
		[SaveableField(14)]
		public int Casualties;

		// Token: 0x04000C7C RID: 3196
		[SaveableField(16)]
		private readonly MapEvent _mapEvent;

		// Token: 0x04000C7D RID: 3197
		[CachedData]
		private List<UniqueTroopDescriptor> _simulationTroopList;

		// Token: 0x04000C7E RID: 3198
		[SaveableField(130)]
		private IFaction _mapFaction;

		// Token: 0x04000C7F RID: 3199
		[SaveableField(23)]
		private int _selectedSimulationTroopIndex;

		// Token: 0x04000C80 RID: 3200
		[SaveableField(24)]
		private UniqueTroopDescriptor _selectedSimulationTroopDescriptor;

		// Token: 0x04000C81 RID: 3201
		[SaveableField(25)]
		private CharacterObject _selectedSimulationTroop;

		// Token: 0x04000C82 RID: 3202
		private TroopUpgradeTracker _troopUpgradeTracker;

		// Token: 0x04000C83 RID: 3203
		[SaveableField(26)]
		internal bool IsSurrendered;

		// Token: 0x04000C84 RID: 3204
		[SaveableField(27)]
		private MBList<MobileParty> _nearbyPartiesAddedToPlayerMapEvent = new MBList<MobileParty>();
	}
}
